using System;
using System.Collections.Generic;
using System.Linq;
using Arcane.Source.Scripting;

namespace Arcane.Source.Story.Data
{
    public class Conversation
    {
        public int flags;
        public Dialog dialogRoot;

        public Conversation Load(Ast ast)
        {
            var ret = new Conversation();
            if (ast["flags"] is Value v)
            {
                ret.flags = v.value.AsInt32();
            }

            if (ast["dialogs"] is Compound dialogs)
            {
                var entry = string.Empty;
                var queue = new Queue<KeyValuePair<string, DialogObj>>();

                foreach (KVPair dialogKv in dialogs.KVPairs)
                {
                    switch (dialogKv.key.ToString())
                    {
                        case "entry":
                            entry = dialogKv.value.ToString();
                            break;
                        case string s:
                            queue.Enqueue(new(s, DialogObj.From(dialogKv.value)));
                            break;
                    }
                }

                var root = Link(entry, queue);
            }


            return ret;
        }

        private Dialog Link(string entry, Queue<KeyValuePair<string, DialogObj>> objs)
        {
            var target = new Dictionary<string, Dialog>();
            short iterCount = 0;

            while (objs.Count > 0)
            {
                if (iterCount > 255) throw new System.Exception("dialog link overflow.");

                var obj = objs.Dequeue();
                foreach (var next in obj.Value.next.Values)
                {
                    if (next is Done) continue;
                    var ast = ((Unresolved)next).ast;
                    
                }
            }

            throw new NotImplementedException();
        }


        private abstract class DialogLink;

        private class Unresolved(Ast ast) : DialogLink
        {
            public Ast ast = ast;
        }

        private class Done(Dialog dialog) : DialogLink
        {
            public Dialog dialog = dialog;
        }

        private class DialogObj
        {
            public string character;
            public string message;
            public Dictionary<string, DialogLink> next = [];
            public DialogLink defaultNext;

            public static DialogObj From(Ast ast)
            {
                if (ast is not Compound c) return null;

                var ret = new DialogObj();
                foreach (KVPair field in c.KVPairs)
                {
                    switch (field.key.ToString())
                    {
                        case "character":
                            ret.character = field.value.ToVariant().AsString();
                            break;

                        case "message":
                            ret.message = field.value.ToVariant().AsString();
                            break;

                        case "next":
                            foreach (KVPair links in (field.value as Compound).KVPairs)
                            {
                                switch (links.key)
                                {
                                    case Value s:
                                        ret.next.Add(s.ToString(), new Unresolved(links.value));
                                        break;

                                    case Ident id when id.name == "default":
                                        ret.defaultNext = new Unresolved(links.value);
                                        break;
                                }
                            }
                            break;
                    }
                }
                return ret;
            }
        }
    }
}